package com.junzhiit.nengji.api.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.junzhiit.nengji.api.service.PostageTemplateService;
import com.junzhiit.nengji.api.web.vo.FreightVO;
import com.junzhiit.nengji.bo.GoodsBO;
import com.junzhiit.nengji.bo.GoodsDetailBO;
import com.junzhiit.nengji.dao.AddressDAO;
import com.junzhiit.nengji.dao.PostageConditionDAO;
import com.junzhiit.nengji.model.Address;
import com.junzhiit.nengji.model.PostageCondition;
import com.junzhiit.nengji.model.enums.PostageType;

@Service
public class PostageTemplateServiceImpl extends BaseServiceImpl implements PostageTemplateService {
	
	@Autowired
	private PostageConditionDAO postageConditionDAO;
	
	@Autowired
	private AddressDAO addressDAO;
	
	@Override
	public FreightVO freight(String userId,String areaCode,Map<String,Map<GoodsBO,Integer>> goodsMap) {
		FreightVO vo = new FreightVO();
		Double totalFreight = new Double(0);
		List<GoodsBO> noSupportList = new ArrayList<GoodsBO>();
		StringBuffer noSupportGoodsIds = new StringBuffer();
		Map<String,Double> freightMap = new HashMap<String,Double>();
		Set<String> keySet = goodsMap.keySet();
		Iterator<String> iterator =  keySet.iterator();
		//以下是按照每个店铺计算
		while(iterator.hasNext()){
			//统一运费计算
			Double unifiedFreight = new Double(0);
			String key = iterator.next();
			Map<GoodsBO,Integer> goodsAndNumber = goodsMap.get(key);
			//按照运费模版ID归类商品
			Map<String,Map<GoodsBO,Integer>> map = new HashMap<String,Map<GoodsBO,Integer>>();
			for(Entry<GoodsBO, Integer> goodsAndNumberEntry :goodsAndNumber.entrySet()){
				GoodsBO goods = goodsAndNumberEntry.getKey();
				//1.商品如果是统一运费 则按照最高的统一运费计算
				if(goods.getPostageType() == PostageType.UNIFY.toIntValue()){
					if(unifiedFreight == 0){
						unifiedFreight = goods.getPostagePrice();
					}else{
						if(goods.getPostagePrice()>unifiedFreight){
							unifiedFreight = goods.getPostagePrice();
						}
					}
				}else if(goods.getPostageType() == PostageType.TEMPLATE.toIntValue()){
					//如果是按照运费模版
					if(map.containsKey(goods.getPostageTemplateId())){
						Map<GoodsBO,Integer> goodsAndNumberMap = map.get(goods.getPostageTemplateId());
						goodsAndNumberMap.put(goods, goodsAndNumberEntry.getValue());
					}else{
						Map<GoodsBO,Integer> goodsAndNumberMap = new HashMap<GoodsBO,Integer>();
						goodsAndNumberMap.put(goods, goodsAndNumberEntry.getValue());
						map.put(goods.getPostageTemplateId(), goodsAndNumberMap);
					}
				}
			}
			/**
			 * 处理运费模版
			 * 1.首先查询出用户的运费模版
			 * 2.遍历按照运费模版分好类的map
			 * 3.
			 * */
			if(map.size()>0){
				if(StringUtils.isBlank(areaCode)){
					Address address = addressDAO.getDefalutAddress(userId);
					areaCode = address.getAreaCode();
				}
				
				// 首重/首金额最大的
				PostageCondition maxPostageCondition = null;
				/**
				 * 遍历出 首重/首金额最大的
				 * 1.如果是相同运费模版：按商品累加运费的计算方式，按该模板设置的规则计算。则此处求得的是符合用户区域内的运费模版。
	         	 *	例如商品A，B都是用模板M（首件10块，续2件5块），如果购买商品A和B，各一件，则一共购买两件，运费=10+5=15元。
				 * 2.如果是不同的运费模版。则此处求得的是附和拥护区域内首重/首金额最大的。
				 * */ 
				//找出该店铺下所有运费模版最高标准 
				for (Entry<String,Map<GoodsBO,Integer>> entry : map.entrySet()) {
					List<PostageCondition> list = postageConditionDAO.findAll(entry.getKey());
					int count = 0;
					for(PostageCondition postageCondition:list){
						String[] src = postageCondition.getAreaCode().split(",");
						boolean boo = compare(src,areaCode);
						if(boo){
							if(maxPostageCondition == null){
								maxPostageCondition = postageCondition;
							}else{
								if((postageCondition.getBasicQuality()/postageCondition.getBasicPostage()) > (maxPostageCondition.getBasicQuality()/maxPostageCondition.getBasicPostage())){
									maxPostageCondition = postageCondition;
								}
							}
						}else{
							count++;
						}
					}
					if(count == list.size()){
						for (Entry<GoodsBO,Integer> noSupportEntry : entry.getValue().entrySet()) {
							GoodsBO noGoodsBO = noSupportEntry.getKey();
							noSupportList.add(noGoodsBO);
							noSupportGoodsIds.append(noGoodsBO.getId()+",");
						}
					}
				}
				if(noSupportList.size()<=0){
					Double cost = maxPostageCondition.getBasicPostage();
					// 该运费模版下商品总重量
					Double totalWeight = new Double(0);
					for (Entry<String, Map<GoodsBO, Integer>> entry : map.entrySet()) {
						for (Entry<GoodsBO, Integer> goodsAndNumberEntry : entry.getValue().entrySet()) {
							GoodsBO goods = goodsAndNumberEntry.getKey();
							totalWeight += (goods.getPostageWeight() * goodsAndNumberEntry.getValue());
						}
					}
					
					// 续重
					Double continuedWeight =  totalWeight - maxPostageCondition.getBasicQuality();
					//计算续费
					if(continuedWeight>0){
						//续费
						Double continuedCost = continuedWeight.intValue()*maxPostageCondition.getIncrementPostage();
						if((continuedWeight-continuedWeight.intValue())>0){
							continuedCost += maxPostageCondition.getIncrementPostage();
						}
						cost += continuedCost;
					}
					totalFreight += (cost + unifiedFreight);
					freightMap.put(key, (cost + unifiedFreight));
				}
			}else{
				totalFreight += unifiedFreight;
				freightMap.put(key, unifiedFreight);
			}
		}
		
		if(noSupportList.size()>0){
			vo.setNoSupport(false);
			vo.setNoSupportList(noSupportList);
		}
		if(noSupportGoodsIds.length()>1){
			noSupportGoodsIds.delete(noSupportGoodsIds.length()-1, noSupportGoodsIds.length());
		}
		vo.setNoSupportGoodsIds(noSupportGoodsIds.toString());
		vo.setFreightMap(freightMap);
		vo.setTotalFreight(totalFreight);
		return vo;
	}
	
	private boolean compare(String []src ,String target){
		boolean boo = false;
		for(int i =0,t = src.length;i<t;i++){
			if(src[i].equals(target)){
				boo = true;
				break;
			}
		}
		return boo;
	}
	
	@Override
	public void transformation(Map<GoodsBO,Integer> goodsMap,GoodsDetailBO source){
		GoodsBO goods = new GoodsBO();
		BeanUtils.copyProperties(source,goods);
		goodsMap.put(goods, source.getNumber());
	}

}
